#include "canbus/message.h"

/**
 * @namespace canbus
 * @brief canbus
 */
namespace canbus {

/**
 * @class CanMsg10
 * @brief Concrete can message that stores general vehicle status information
 */
class CanMsg10: public CanMsg {
public:
  CanMsg10():
  CanMsg(),
  auto_mode(false),
  control_on(false),
  override_bypass(false),
  estop(false),
  parking_brk(false),
  gantry_running(false),
  hoist_running(false),   
  gantry_permit(false),
  container_landed(false),
  spreader_locked(false),
  spreader_unlocked(false),
  s_down_front_right(false),
  s_down_front_left(false),
  s_down_back_right(false),
  s_down_back_left(false),
  spreader_size(0),
  wheel_direction_fl(false),
  wheel_direction_fr(false),
  wheel_direction_rl(false),
  wheel_direction_rr(false) 
  {}

  CanMsg10(uint8_t* value): 
  CanMsg(value),
  auto_mode(false),
  control_on(false),
  override_bypass(false),
  estop(false),
  parking_brk(false),
  gantry_running(false),
  hoist_running(false),   
  gantry_permit(false),
  container_landed(false),
  spreader_locked(false),
  spreader_unlocked(false),
  s_down_front_right(false),
  s_down_front_left(false),
  s_down_back_right(false),
  s_down_back_left(false),
  spreader_size(0),
  wheel_direction_fl(false),
  wheel_direction_fr(false),
  wheel_direction_rl(false),
  wheel_direction_rr(false) 
  {}
  
  virtual ~CanMsg10() = default;

  void UpUpdateData() {
    // 1st byte
    Byte status_1(data_ + 0);
    auto_mode = status_1.is_bit_1(0);
    control_on = status_1.is_bit_1(1);
    override_bypass = status_1.is_bit_1(3);
    estop = status_1.is_bit_1(4);
    parking_brk = status_1.is_bit_1(5);
    gantry_running = status_1.is_bit_1(6);
    hoist_running = status_1.is_bit_1(7);
    gantry_permit = auto_mode && control_on && parking_brk;

    // 2nd byte
    Byte status_2(data_ + 1);
    container_landed = status_2.is_bit_1(0);
    spreader_locked = status_2.is_bit_1(1);
    spreader_unlocked = status_2.is_bit_1(2);
    s_down_front_right = status_2.is_bit_1(3);
    s_down_front_left = status_2.is_bit_1(4);
    s_down_back_right = status_2.is_bit_1(5);
    s_down_back_left = status_2.is_bit_1(6);

    // 3rd byte
    Byte status_3(data_ + 2);
    int spreader_size = status_3.get_byte(0, 8);

    // 4th byte
    Byte status_4(data_ + 3);
    wheel_direction_fl = status_4.is_bit_1(0);
    wheel_direction_fr = status_4.is_bit_1(2);
    wheel_direction_rl = status_4.is_bit_1(4);
    wheel_direction_rr = status_4.is_bit_1(6);
  } 

  template <typename T>
  void DownUpdateData(const T& input_data) {}

  static const int32_t ID;
  static const std::string NAME;

  // 1st byte
  bool auto_mode;
  bool control_on;
  bool override_bypass;
  bool estop;
  bool parking_brk;
  bool gantry_running;
  bool hoist_running;   
  bool gantry_permit;

  // 2nd byte
  bool container_landed;
  bool spreader_locked;
  bool spreader_unlocked;
  bool s_down_front_right;
  bool s_down_front_left;
  bool s_down_back_right;
  bool s_down_back_left;

  // 3rd byte
  int spreader_size;

  // 4th byte
  bool wheel_direction_fl;
  bool wheel_direction_fr;
  bool wheel_direction_rl;
  bool wheel_direction_rr;

  friend class CanbusHandler;
};

}